#include "kernel.h"

/* init_pics()
 * init the PICs and remap them
 */
void play_pics(long int pic1, long int pic2)
{
	int a;
	for (a = 0; a < 1000; a ++)
	{
		outb(PIC1, (unsigned char)ICW4);
		outb(PIC2, (unsigned char)0xffff);
		outb(PIC1, (unsigned char)ICW1);
		outb(PIC2, (unsigned char)0xffff);
	}
		

	/* send ICW2 */
	outb(PIC1 + 1, pic1);	/* remap */
	outb(PIC2 + 1, pic2);	/*  pics */

	/* send ICW3 */
	outb(PIC1 + 1, (unsigned char)0xffff);	/* IRQ2 -> connection to slave */
	outb(PIC2 + 1, (unsigned char)0xffff);

	/* send ICW4 */
	outb(PIC1 + 1, ICW4);
	outb(PIC2 + 1, ICW4);

	/* disable all IRQs */
	outb(PIC1 + 1, 0xFF);
}

void pcnet_ops()
{
	char dest[6] = {0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD};
	unsigned int type = 0x0800;
	unsigned char packet[1000];
	unsigned int len;
	IP(packet, &len);
	ICMP(packet, &len, 0x8, 0x0, FILL, 0x4b11, 0x1);
	
	packet[2] = (len >> 8) & 0xff;
	packet[3] = len & 0xff;

	unsigned int ip_checksum = checksum((unsigned short *) packet, ip_len); 
        packet[ip_checksum_loc] = ip_checksum & 0xff;                                          
        packet[ip_checksum_loc + 1] = (ip_checksum >> 8) & 0xff;

	print ((unsigned char *) "Kernel: Doing pcnet operations\n");
	pcnet32_probe1(pcnet_entry_point);

	pcnet32_reset(pcnet_entry_point);
	pcnet32_transmit(dest, type, len, packet);
}

void test_numbers()
{
		int result = 0;
		print("Testing number and string functions:\n");
	
		unsigned char *value_a = (unsigned char *) "bb";
		htos(0xa, value_a);
		if((!strcmp(value_a, (unsigned char *) "a"))) {
			print("1 . htos(0xa): ");
			print(value_a);
			print(CRLF);
			result ++;
		}
			
		unsigned char value_0[2];
		htos(0x0, value_0);
		if((!strcmp(value_0 , (unsigned char *) "0"))) {
			print("2 . htos(0x0): ");
			print(value_0);
			print(CRLF);
			result ++;
		}

		unsigned char *value_1 = (unsigned char *) "more space";
		htos(0x1, value_1);
		if((!strcmp(value_1 , (unsigned char *) "1"))) {
			print("3 . htos(0x1): ");
			print(value_1);
			print(CRLF);
			result ++;
		}

		unsigned char value_1234[5];
		htos(0x1234, value_1234);

		if((!strcmp(value_1234 , (unsigned char *) "1234"))) {
			print("4 . htos(0x1234): ");
			print(value_1234);
			print(CRLF);
			result ++;
		}

		unsigned char *value_12ab = (unsigned char *) "exact";
		htos(0x12ab, value_12ab);
		if((!strcmp(value_12ab , (unsigned char *) "12ab"))) {
			print("5 . htos(0x12ab): ");
			print(value_12ab);
			print(CRLF);
			result ++;
		}

		unsigned char value_ab[3];
		htos(0xab, value_ab);
		if((!strcmp(value_ab , (unsigned char *) "ab"))) {
			print("6 . htos(0xab): ");
			print(value_ab);
			print(CRLF);
			result ++;
		}

		unsigned char value_11h[2];
		htos(ctoh(htoc(0xb)), value_11h);	
		if ((!strcmp(value_11h , (unsigned char *) "b"))) {
			print("7 . print(htos(ctoh(htoc(0xb)))): ");
			print(value_11h);
			print(CRLF);
			result ++;
		}

		unsigned char value_5h[2];
		htos(ctoh(htoc(0x5)), value_5h);
		if ((!strcmp(value_5h , (unsigned char *) "5"))) {
			print("8 . print(htos(ctoh(htoc(0x5)))): ");
			print(value_5h);
			print(CRLF);
			result ++;
		}

		unsigned char *test_1 = (unsigned char *) "abcdabcd";
		unsigned char test_2[9];
		htos(stoh(test_1, RIGHT_TO_LEFT), test_2);
		if ((!strcmp(test_2 , (unsigned char *) "dcbadcba"))) {
			print("9 . print(htos(stoh(\"abcdabcd\", RIGHT_TO_LEFT))): ");
			print(test_2);
			print(CRLF);
			result ++;
		}

		unsigned char test_3[5];
		htos(stoh((unsigned char *) "bcde", LEFT_TO_RIGHT), test_3);
		if ((!strcmp(test_3 , (unsigned char *) "bcde"))) {
			print("10. print(htos(stoh(\"bcde\", LEFT_TO_RIGHT))): ");
			print(test_3);
			print(CRLF);
			result ++;
		}

		unsigned char *test_6 = (unsigned char *) "abcdeabc";	
		unsigned char test_7[9];
		htos(stoh(test_6, RIGHT_TO_LEFT), test_7);
		if ((!strcmp(test_7 , (unsigned char *) "cbaedcba"))) {
			print("11. print(htos(stoh(test_6, RIGHT_TO_LEFT))): ");
			print(test_7);
			print(CRLF);
			result ++;
		}

		unsigned char *test_8 = (unsigned char *) "test_8";
		unsigned char test_8_addr[5];
		htos((unsigned int) test_8, test_8_addr);
		if (strcmp(test_8_addr, (unsigned char *) "1")) {
			print("12. Address of test_8: ");
	                print(test_8_addr);
        	        print(CRLF);
			result ++;
		}
		
		unsigned char sizeof_char[2];
		htos((int) sizeof(char), sizeof_char);
		if (!strcmp(sizeof_char, (unsigned char *) "1")) {
	                print( "13. sizeof(char) == ");
        	        print(sizeof_char);
                	print(CRLF); 
			result ++;
		}

		unsigned char value_a0b3[5];
		htos(stoh((unsigned char *) "a0b3", LEFT_TO_RIGHT), value_a0b3);
		if (!strcmp(value_a0b3, (unsigned char *) "a0b3")) {
	                print( "14. htos(stoh(\"a0b3\")) == ");
        	        print(value_a0b3);
                	print(CRLF);
			result ++;
		}

		unsigned char value_0ab3[5];
		htos(stoh((unsigned char *) "ab3", RIGHT_TO_LEFT), value_0ab3);
		if (!strcmp(value_0ab3, (unsigned char *) "3ba")) {
                        print( "15. htos(stoh(\"ab3\")) == ");
                        print(value_0ab3);
                        print(CRLF);
                        result ++;
                }

		unsigned char value_0ab30abe[5];
		htos(stoh((unsigned char *) "0ab30abe", RIGHT_TO_LEFT), value_0ab30abe);
		if (!strcmp(value_0ab30abe, (unsigned char *) "eba03ba0")) {
                        print( "16. htos(stoh(\"0ab30abe\", RIGHT_TO_LEFT)) == ");
                        print(value_0ab30abe);
                        print(CRLF);
                        result ++;
                }

		unsigned char *str1 = (unsigned char *) "test1";
		unsigned char str2[6];
		memcpy(str2, str1, 6);
		if (! strcmp(str2, (unsigned char *) "test1")) {
			print("17. memcpy result: ");
			print(str2);	
			print(CRLF);
			result ++;
		}
	
		unsigned char *str3 = (unsigned char *) "str3";
		unsigned char str4[5];
		strcpy(str3, str4);
		if (! strcmp(str4, (unsigned char *) "str3")) {
			print("18. strcpy result: ");
			print(str3);	
			print(CRLF);
			result ++;
		}

                unsigned char str5[5];
                memset(str5, 'a', 4);
		str5[4] = '\0';
                if (! strcmp(str5, "aaaa")) {
                        print("19. memset result: ");
                        print(str5);
                        print(CRLF);
                        result ++;
                }

		unsigned char result_str[2];
		print("Number of tests passed:");
		htos(result, result_str);
		print(result_str);
		print(CRLF);

		if (result != 19) {
			print("some test failed\n");
		} else {
			print("All tests passed successfully\n");
		}
}	

void display_help()
{
                cls();
                print("help-> This message\n");
                print("cls-> Clear Screen\n");
                print("pcnetops-> PCNet Operations\n");
                print("playpics-> PIC Operations\n");
                print("testnum-> Test number and string functions\n");
                print("timerticks-> Print timer ticks\n");
}
